home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
dskut
/
pausedev.zip
/
PAUSEDEV.PAS
< prev
Wrap
Pascal/Delphi Source File
|
1993-01-23
|
4KB
|
142 lines
{$S-,F-} { Stack checking wouldn't work here, and we assume near calls
}
{$X+} { Extended syntax }
{$M $1000,0,0} { We won't use the heap or stack. }
program pausedev;
{ This program implements a PAUSE command either as DEVICE=PAUSEDEV.EXE
or executed from the command line. }
uses opint, { OPro interrupt services, needed for stack switching }
crt; { Standard I/O unit that doesn't rely on DOS }
procedure strategy_routine(bp:word); interrupt; forward;
procedure interrupt_routine(bp:word); interrupt; forward;
procedure call_Main_Block; forward;
{ This procedure must come first!!! }
procedure header;
assembler;
asm
dd $FFFFFFFF { next driver }
dw $8000 { attributes of simple character device }
dw offset strategy_routine
dw offset interrupt_routine
db 'PAUSE '
end;
const
stDone = $100;
stBusy = $200;
cmInit = 0;
device_driver : boolean = false;
type
request_header = record
request_length : byte;
subunit: byte;
command_code : byte;
status : word;
reserved: array[1..8] of byte;
num_units : byte;
first_free : pointer;
args : ^char;
drive_num : byte;
end;
var
local_stack : array[1..4000] of byte;
end_of_stack : byte;
request : ^request_header;
procedure handler(var regs : intregisters);
{ This routine is called by the strategy routine, and handles all requests.
The data segment is okay, and we're running on the local_stack so we've got
plenty of space. Remember: the init sections haven't been called yet!
}
begin
with request^ do
begin
case command_code of
cmInit: begin
device_driver := true;
Call_Main_Block;
first_free := ptr(cseg,0); { Release everything!! }
status := stDone;
end;
else
status := stBusy;
end;
end;
end;
procedure RetFar; assembler;
{ Replacement for the IRET code that ends the interrupt routines below }
asm
mov sp,bp
pop bp
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
retf
end;
procedure strategy_routine(bp:word);
var
regs : intregisters absolute bp;
begin
with regs do
request := ptr(es,bx);
RetFar;
end;
procedure interrupt_routine(bp:word);
var
regs : intregisters absolute bp;
begin
SwapStackandCallNear(Ofs(handler),@end_of_stack,regs);
RetFar;
end;
procedure do_pause;
begin
while keypressed do readkey;
writeln('Press any key to continue....');
repeat until keypressed;
end;
procedure Ret_From_Main_Block; assembler; { Must have declaration just
like Call_Main_Block }
asm
end;
procedure Call_Main_Block; assembler; { Must come just before main
entry point }
asm
db $eb, 6 { Jump over the Ret instruction
and System init }
end;
begin
do_pause;
if Device_Driver then
asm
pop bp
jmp Ret_From_Main_Block;
end
else
halt;
header; { This line is never reached, but it fools the linker
so that everything is loaded properly. }
end.